<?php

class Controller extends Object {
    // An array containing the class names of models this controller uses.
    var $uses = null;

    var $plugin_uses = null;

    var $components = null;

    var $plugin_components = null;

    // Parameters received in the current request: GET and POST data, information about the request, etc.
    var $data = array();

    var $modelClass = null;

    var $autoRender = true;

    var $layout = 'admin';

    var $helpers = array('Html');

    var $viewVars = array();

    var $no_session = array('flash_get_uploaded','flash_upload_file');

    var $referer = null;

    var $header_notice = null;

    var $session_key = array();

    function redirect($url, $force = false) {
        if ($force) {
            al_redirect($url);
        } else {
            al_redirect('/' . ARLICLE_ADMIN . $url);
        }
        exit();
    }

    function set($key, $value) {
        $this->viewVars[$key] = $value;
    }

    function render() {
        $this->ini_render();
        require LIBS . 'views/helper.php';
        $helpers = $this->helpers;
        if (is_array($helpers)) {
            foreach($helpers as $helper) {
                $helper_low = strtolower($helper);
                require LIBS . 'views/helpers/' . $helper_low . '.php';
                $helper = $helper . 'Helper';
                ${$helper_low} =& new $helper();
                ${$helper_low}->data =& $this->data;
            }
        }
        if (is_array($this->viewVars)) {
            extract($this->viewVars, EXTR_OVERWRITE);
        }

        if ($this->layout) {
            nocache_headers();
            require ARLICLE . 'app/view/layouts/' . $this->layout . '.php';
        }
    }

    function ini_render() {
        if (!empty($this->header_notice)) {
            $this->set('noticemessage_status', '');
            $this->set('noticemessage', $this->header_notice);
        } else {
            $this->set('noticemessage_status', 'style="display:none"');
            $this->set('noticemessage', null);
        }
    }

    // Gets the referring URL of this request
    function referer() {
        
    }

    // Check admin
    function auth_redirect() {
        if (Router::is_admin()) {
            $class_methods = get_class_methods(get_class($this));
            if (!in_array($this->action, $class_methods)) {
                $this->error_404();
            }
            if (!in_array($this->action, $this->no_session)) {
                $current_user = current_user();
                if (!empty($current_user->id)) {
                    if ($this->file_name != 'login') {
                        if (!current_user_can($this->file_name, 'read')) {
                            $this->error_404();
                        }
                    }
                    $this->set('current_username', $current_user->username);
                    return true;
                }

                if ($this->file_name != 'login') {
                    $this->redirect('/login?' . urlencode($this->url()));
                    exit();
                }
            }
        }
    }

    function url() {
        $url = str_replace(Router::get_url(), '', env('REQUEST_URI'));
        return str_replace(sprintf('/%s', ARLICLE_ADMIN), '', $url);
    }

    // Starts the components linked to this controller.
    function _init_components() {
        if ($this->components !== null) {
            foreach($this->components as $component) {
                $component_file = ARLICLE . 'app/controller/components/' . $component . '.php';
                require $component_file;
            }
        }
        if ($this->plugin_components !== null) {
            foreach($this->plugin_components as $component) {
                $plugin_component_file = PLUGIN . '/app/controller/components/' . $component . '.php';
                    if (file_exists($plugin_component_file)) {
                        require $plugin_component_file;
                    }
            }
        }
    }

    // Loads Model classes based on the the uses property
    function construct_classes() {
        require LIBS . 'model/model.php';
        if (!empty($this->plugin_uses)) {
            $plugin_uses = is_array($this->plugin_uses) ? $this->plugin_uses : array($this->plugin_uses);
            $app = PLUGIN . '/app/';
            foreach($this->plugin_uses as $modelClass) {
                $this->load_model($modelClass, $app);
                if (isset($this->data[$modelClass])) {
                    $this->data[$modelClass] = $this->field_sanitize($this->$modelClass, $this->data[$modelClass]);
                }
            }
        }

        if (empty($this->uses)) {
            return false;
        }

        $uses = is_array($this->uses) ? $this->uses : array($this->uses);

        $app = ARLICLE . 'app/';
        foreach($uses as $modelClass) {
            $this->load_model($modelClass, $app);
            if (isset($this->data[$modelClass])) {
                $this->data[$modelClass] = $this->field_sanitize($this->$modelClass, $this->data[$modelClass]);
            }
        }
        return true;
    }

    // Loads and instantiates models required by this controller.
    function load_model($modelClass, $app) {
        $modelClass_file = inflect($modelClass);
        $load_modelClass_file = $app . 'model/' . $modelClass_file . '.php';
        require $load_modelClass_file;
        $this->{$modelClass} =& new $modelClass();
    }

    function field_sanitize($modelClass, $data) {
        $results = array();
        if (is_array($data)) {
            foreach($data as $field => $value) {
                $filter = $field . '_sanitize';
                if (method_exists($modelClass, $filter)) {
                    $results[$field] = call_user_func_array(array($modelClass->name, $filter), $value);
                } else {
                    $results[$field] = $value;
                }
            }
        }
        return $results;
    }

    function __get_session_data($session = null) {
        if (empty($session))
            die(__('Time out, Please login again'));
        $expire = time() - 86400;
        $this->Sessions->del_all("created<='$expire'");
        $this->Sessions->id = $session;

        $session_data = $this->Sessions->read('created,data');
        if (empty($session_data)) {
            die(__('Time out, Please login again'));
        }

        if (!empty($session_data->data)) {
            $session_data = unserialize($session_data->data);
        } else {
            $session_data = array();
        }

        if (!empty($this->session_key)) {
            foreach($this->session_key as $key) {
                if (!isset($session_data[$key])) {
                    $session_data[$key] = null;
                }
            }
        }
        return $session_data;
    }

    function error_404() {
        error_404();
    }
}

?>
